\lstset{language=C++}
\begin{lstlisting}[caption=cast-test.cc]
// Copyright 2009 Pigasus.
// GNU GPL v2.
// Author: John Zhang.

#include "MiniCppUnit-2.5/MiniCppUnit.hxx"

#include <string>

#include "../src/pigasus-types.h"
#include "../src/cast.h"

class CastTest : public TestFixture<CastTest> {
 public:
  TEST_FIXTURE(CastTest) {
    TEST_CASE(TestCastingToInt);
    TEST_CASE(TestCastingToFloat);
    TEST_CASE(TestCastingToString);
    TEST_CASE(TestCastingFromVoid);
    TEST_CASE(TestCastingToFile);
    TEST_CASE(TestCastingToOwnType);
  }

  void TestCastingToInt() {
    int original_int = 42;
    int result = CastToInt(original_int);
    ASSERT_EQUALS(result, original_int);

    string test_str = "   42!!\n\n\t";
    result = CastToInt(test_str);
    ASSERT_EQUALS(result, original_int);
    test_str = "42";
    result = CastToInt(test_str);
    ASSERT_EQUALS(result, original_int);

    double test_float = 42.1;
    result = CastToInt(test_float);
    ASSERT_EQUALS(result, original_int);
    test_float = 42.5;
    result = CastToInt(test_float);
    ASSERT_EQUALS(result, original_int+1);
  }

  void TestCastingToFloat() {
    double original_float = 123.45;
    double result = CastToFloat(original_float);
    ASSERT_EQUALS(result, original_float);

    string test_str = "    123.45   \n";
    result = CastToFloat(test_str);
    ASSERT_EQUALS(result, original_float);
    test_str = "123.45";
    result = CastToFloat(test_str);
    ASSERT_EQUALS(result, original_float);

    int test_int = 123;
    result = CastToFloat(test_int);
    ASSERT_EQUALS(result, 123.0);
  }

  void TestCastingToString() {
    string original_string = "-12345";
    int test_int = -12345;
    string result = CastToString(test_int);
    ASSERT_EQUALS(result, original_string);

    double test_float = -12345.0;
    string expected_string = "-12345";
    result = CastToString(test_float);
    ASSERT_EQUALS(result, expected_string);

    expected_string = "bob";
    result = CastToString(expected_string);
    ASSERT_EQUALS(result, expected_string);
  }

  void TestCastingFromVoid() {
    string test_str = "bob";
    double test_float = 0.25;
    int test_int = 42;

    List list_of_string = NewList(test_str);
    Map map_of_int(test_str, test_int);
    List buffer;

    File test_file(test_str + ".txt");

    buffer.Append(test_str);
    buffer.Append(test_float);
    buffer.Append(test_int);
    buffer.Append(list_of_string);
    buffer.Append(map_of_int);
    buffer.Append(test_file);

    string result_str = CastToString(buffer[0]);
    ASSERT_EQUALS(result_str, test_str);
    double result_float = CastToFloat(buffer[1]);
    ASSERT_EQUALS(result_float, test_float);
    int result_int = CastToInt(buffer[2]);
    ASSERT_EQUALS(result_int, test_int);

    List result_list = CastToList(buffer[3]);
    result_str = CastToString(result_list[0]);
    ASSERT_EQUALS(result_str, test_str);
    Map result_map = CastToMap(buffer[4]);
    result_int = CastToInt(result_map[test_str]);
    ASSERT_EQUALS(result_int, test_int);

    File result_file = CastToFile(buffer[5]);
    ASSERT_EQUALS(test_str + ".txt", result_file.Filename());
  }

  void TestCastingToFile() {
    string test_str = "bob.txt";
    File test_file(test_str);
    ASSERT_EQUALS(test_str, test_file.Filename());
  }

  void TestCastingToOwnType() {
    string test_str = "bob";
    int test_int  = 42;
    
    List original_list = NewList(test_str);
    List result_list = CastToList(original_list);
    ASSERT_EQUALS(CastToString(original_list[0]),
                  CastToString(result_list[0]));
    result_list.Append(test_int);
    ASSERT_EQUALS(CastToInt(result_list[1]), test_int);

    Map original_map(test_str, test_int);
    Map result_map = CastToMap(original_map);
    ASSERT_EQUALS(CastToInt(original_map[test_str]),
                  CastToInt(result_map[test_str]));

    File original_file(test_str + ".txt");
    File result_file = CastToFile(original_file);
    ASSERT_EQUALS(original_file.Filename(), result_file.Filename());
  }
};

REGISTER_FIXTURE(CastTest);
\end{lstlisting}

\lstset{language=C++}
\begin{lstlisting}[caption=formatstring-test.cc]
// Copyright 2009 Pigasus.
// GNU GPL v2.
// Author: John Zhang.

#include "MiniCppUnit-2.5/MiniCppUnit.hxx"

#include <string>

#include "../src/pigasus-types.h"
#include "../src/formatstring.h"

class CastTest : public TestFixture<CastTest> {
 public:
  TEST_FIXTURE(CastTest) {
    TEST_CASE(TestFloatPrinting);
    TEST_CASE(TestIntPrinting);
    TEST_CASE(TestStringPrinting);
    TEST_CASE(TestMixedPrinting);
  }

  void TestFloatPrinting() {
    List args;
    args.Append(0.25);

    string result = FormatString("%lf", args);
    ASSERT_EQUALS(result, "0.250000");

    args.Append(-0.00001);
    args.Append(10.0);

    result = FormatString("%lf %0.2lf %.0lf", args);
    ASSERT_EQUALS(result, "0.250000 -0.00 10");

    result = FormatString("hello %0.2lf world! %0.10lf%%%0.2lf\n", args);
    ASSERT_EQUALS(result, "hello 0.25 world! -0.0000100000%10.00\n");
  }

  void TestIntPrinting() {
    List args;
    args.Append(1);

    string result = FormatString("%d", args);
    ASSERT_EQUALS(result, "1");
    result = FormatString("%5d", args);
    ASSERT_EQUALS(result, "    1");
    result = FormatString("%02d", args);
    ASSERT_EQUALS(result, "01");

    args.Append(100001);
    args.Append(-10);
    args.Append(42);
    result = FormatString("%d %d %03d %d", args);
    ASSERT_EQUALS(result, "1 100001 -10 42");

    result = FormatString("hello%dworld!", args);
    ASSERT_EQUALS(result, "hello1world!");

    result = FormatString("hello%%%02dworld!\n\n%d\t%d\n", args);
    ASSERT_EQUALS(result, "hello%01world!\n\n100001\t-10\n");
  }

  void TestStringPrinting() {
    List args;
    args.Append("bob");

    string result = FormatString("%s", args);
    ASSERT_EQUALS(result, "bob");
    result = FormatString("hello %s!", args);
    ASSERT_EQUALS(result, "hello bob!");

    args.Append("jane");
    args.Append("bill");
    args.Append("judy");
    result = FormatString("%s%%", args);
    ASSERT_EQUALS(result, "bob%");
    result = FormatString("%s%s%s%s", args);
    ASSERT_EQUALS(result, "bobjanebilljudy");
    result = FormatString("%%%s%%%s%%%s%%%s%%", args);
    ASSERT_EQUALS(result, "%bob%jane%bill%judy%");
  }

  void TestMixedPrinting() {
    List args;
    args.Append(42);
    args.Append(-10.5);
    args.Append("jane");
    args.Append("bob");
    args.Append(43.0);
    args.Append(-10.0000001);

    string result = FormatString("%d:%lf\n%s", args);
    ASSERT_EQUALS(result, "42:-10.500000\njane");

    result = FormatString("%d%0.0lf%s%s%%%%%%%0.5lf", args);
    ASSERT_EQUALS(result, "42-10janebob%%%43.00000");
    
    result = FormatString("%5d\n\t%0.0lf%s%s%0.5lf%lf%%", args);
    ASSERT_EQUALS(result, "   42\n\t-10janebob43.00000-10.000000%");
  }
};

REGISTER_FIXTURE(CastTest);
\end{lstlisting}

\lstset{language=C++}
\begin{lstlisting}[caption=grammar-test.sh]
# Grammar Testing
# Pigasus Language
# Philip Tjimos

cp ../src/grammar/pigasus.lpp ./
cp ../src/grammar/pigasus-grammar.ypp ./

# build the translator
flex -+ pigasus.lpp
bison pigasus-grammar.ypp
g++ pigasus-grammar.tab.cpp

# main function_definition
echo -n "Testing main... "
echo "void main() {" > test.pig
echo "int a;" >> test.pig 
echo "}" >> test.pig
./a.out < test.pig > result.cc
diff -bBws result.cc ./samples/main1.cc

echo -n "Testing main with input... "
echo "void main( list inputs ) {" > test.pig
echo "int a;" >> test.pig 
echo "}" >> test.pig
./a.out < test.pig > result.cc
diff -bBws result.cc ./samples/main2.cc

# other function_definitions
echo -n "Testing functions with all return values... "
echo "int foo( ) {}" > test.pig
echo "void foo2( ) {}" >> test.pig
echo "float foo3( ) {}" >> test.pig
echo "string foo4( ) {}" >> test.pig
echo "list foo5( ) {}" >> test.pig
echo "map foo6( ) {}" >> test.pig
echo "file foo7( ) {}" >> test.pig
./a.out < test.pig > result.cc
diff -bBws result.cc ./samples/type_func.cc

echo -n "Testing functions with different input... "
echo "int foo( int in ) {}" > test.pig
echo "void foo2( file in ) {}" >> test.pig
echo "float foo3( map in ) {}" >> test.pig
echo "string foo4( list in ) {}" >> test.pig
echo "list foo5( string in ) {}" >> test.pig
echo "map foo6( float in ) {}" >> test.pig
echo "file foo7( void in ) {}" >> test.pig
./a.out < test.pig > result.cc
diff -bBws result.cc ./samples/type_func1.cc

echo -n "Testing function with input list... "
echo "void foo ( void in1, int in2, float in3, string in4, list in5, map in6, file in7 ) {}" > test.pig
./a.out < test.pig > result.cc
diff -bBws result.cc ./samples/func_inputlist.cc

# job_definition
echo -n "Testing job definitions... "
echo "job foobar( list a ) {}" > test.pig
./a.out < test.pig > result.cc
diff -bBws result.cc ./samples/job.cc

# statements
echo "void main () {" > test.pig

echo "Testing initialization_statements... "
echo "string myString = \"hello\";" >> test.pig
echo "list myList = [string1, string2, string3];" >> test.pig
echo "map myMap = [name=>myName, pass=>myPass];" >> test.pig

echo "Testing matched_statements... "
echo "if ( i=0 ) { } else { }" >> test.pig

echo "Testing open_statements... "
echo "if ( i=0 ) { }" >> test.pig
echo "if ( i=0 ) { } else if ( i=0 ) { } else { }" >> test.pig

echo "Testing expression_statements... "
echo ";" >> test.pig
echo "int i;" >> test.pig
echo "int i=0;" >> test.pig

echo "Testing iteration_statements... "
echo "while ( i=0 ) { }" >> test.pig
echo "do {} while ( i=0 );" >> test.pig
echo "for (int i=0; i<1; ) { }" >> test.pig
echo "for (;;) { }" >> test.pig
echo "for (int i=0; i<1; i=i+1) { }" >> test.pig

echo "Testing jump_statements... "
echo "continue;" >> test.pig
echo "break;" >> test.pig
echo "return;" >> test.pig
echo "return i=0;" >> test.pig

echo "Testing push_statements... "
echo "int a = push foo, null, null, var;" >> test.pig
echo "push foo, var1, var2, var3;" >> test.pig

echo "Testing wait_statements... "
echo "wait var1;" >> test.pig
echo "waitall;" >> test.pig
echo "}" >> test.pig

echo -n "Result of all statements... "
./a.out < test.pig > result.cc
diff -bBws result.cc ./samples/statements.cc

# maps & lists

echo -n "Testing maps & lists... "
echo "void main() {" > test.pig
echo "list l = [a];" >> test.pig
echo "l = [a];" >> test.pig
echo "l = [a,b];" >> test.pig
echo "l = [a] + [b];" >> test.pig
echo "l = [ [ user=>user1, pass=>pass1], [user=>user2, pass=>pass2] ];" >> test.pig
echo "list l = [ [ user=>user1, pass=>pass1], [user=>user2, pass=>pass2] ];" >> test.pig
echo "l = a + b + [[a,b]] + [c] + d;" >> test.pig
echo "map m = [user => user1];" >> test.pig
echo "m = [user => user1] + [pass => pass1];" >> test.pig
echo "}" >> test.pig
./a.out < test.pig > result.cc
diff -bBws result.cc ./samples/list_maps.cc

# expressions
echo "Testing expressions... "
echo "void main() {" > test.pig
echo "a = 3;" >> test.pig
echo "a=3, b=4, c=5;" >> test.pig

echo "Testing assignment_expressions... "
echo "l = c = d;" >> test.pig
echo "l = [a] + [d] + [e];" >> test.pig
echo "l = [a=>a] + [b=>b] + [c=>c];" >> test.pig

echo "Testing logical_or_expressions... "
echo "if (a || b) { }" >> test.pig

echo "Testing logical_and_expressions... "
echo "if (a && b) { }" >> test.pig

echo "Testing equality_expressions... "
echo "if (a == b) { }" >> test.pig
echo "if (a != b) { }" >> test.pig

echo "Testing rational_expressions... "
echo "if (a < b ) { }" >> test.pig
echo "if (a > b ) { }" >> test.pig
echo "if (a <= b ) { }" >> test.pig
echo "if (a >= b ) { }" >> test.pig

echo "Testing additive_expressions... "
echo "if (a+b < 3) { }" >> test.pig
echo "if (a-b < 3) { }" >> test.pig

echo "Testing multiplicative_expressions... "
echo "if (a+b*3 < 4) { }" >> test.pig
echo "if (a-b/3 < 4) { }" >> test.pig
echo "a = \"test %s\" % myString;" >> test.pig
echo "a = \"test %s%s%s\" % [string1, string2, string3];" >> test.pig
echo "if (a mod b) { }" >> test.pig

echo "Testing cast_expressions... "
echo "int a = (int) b;" >> test.pig
echo "float a = (float) b;" >> test.pig
echo "map a = (map) b;" >> test.pig
echo "list a = (list) b;" >> test.pig
echo "file a = (file) b;" >> test.pig
echo "string a = (string) b;" >> test.pig

echo "Testing unary_expressions... "
echo "loadcsv b;" >> test.pig
echo "int b = length d;" >> test.pig
echo "print \"hello\";" >> test.pig
echo "connect server1;" >> test.pig

echo "Testing system_expressions... "
echo "@{\"run this on the shell\"};" >> test.pig

echo "Testing postfix_expressions... "
echo "int a = array[b];" >> test.pig
echo "int b = func(d);" >> test.pig
echo "int b = func(a,b,c,d);" >> test.pig
echo "int b = func(a=b, c=d);" >> test.pig
echo "} " >> test.pig

echo -n "Result of all expressions... "
./a.out < test.pig > result.cc
diff -bBws result.cc ./samples/expressions.cc

echo ""
echo "Pigasus Grammar Checks Completed"
echo ""

rm result.cc
rm pigMain.cc
rm test.pig
rm *.out
rm *.ypp
rm *.lpp
rm *.cpp
rm foobar.cc
rm lex.yy.cc
\end{lstlisting}

\lstset{language=C++}
\begin{lstlisting}[caption=loadcsv-test.cc]
// Copyright 2009 Pigasus.
// GNU GPL v2.
// Author: John Zhang.

#include "MiniCppUnit-2.5/MiniCppUnit.hxx"

#include <vector>
#include <string>

#include "../src/pigasus-types.h"
#include "../src/loadcsv.h"

class LoadCSVTest : public TestFixture<LoadCSVTest> {
 private:
  void GetValuesFromMap(Map &row, string *host, string *password,
                        string *user) {
    *host = *((string*)(row["host"]));
    *password = *((string*)(row["password"]));
    *user = *((string*)(row["user"]));
  }

 public:
  TEST_FIXTURE(LoadCSVTest) {
    TEST_CASE(TestBasicCSVRead);
    TEST_CASE(TestElementWithNewLine);
  }

  void TestBasicCSVRead() {
    List contents = LoadCSV("samples/csv_test_1.csv");
    string host;
    string user;
    string password;

    GetValuesFromMap(*(Map*)(contents[0]), &host, &password, &user);
    ASSERT_EQUALS(user, "john");
    ASSERT_EQUALS(host, "cepsr");
    ASSERT_EQUALS(password, "zhang");

    GetValuesFromMap(*(Map*)(contents[1]), &host, &password, &user);
    ASSERT_EQUALS(user, "jordan");
    ASSERT_EQUALS(host, "\"csv,bob\"");
    ASSERT_EQUALS(password, "bobo");
  }

  void TestElementWithNewLine() {
    List contents = LoadCSV("samples/csv_test_2.csv");
    string host;
    string user;
    string password;

    GetValuesFromMap(*(Map*)(contents[0]), &host, &password, &user);
    ASSERT_EQUALS(user, "john");
    ASSERT_EQUALS(host, "\"csv,\nbob\"");
    ASSERT_EQUALS(password, "");
  }
};

REGISTER_FIXTURE(LoadCSVTest);

\end{lstlisting}

\lstset{language=C++}
\begin{lstlisting}[caption=pigasus-types-test.cc]
// Copyright 2009 Pigasus.
// GNU GPL v2.
// Author: Phil Tjimos.

#include "MiniCppUnit-2.5/MiniCppUnit.hxx"

#include "../src/pigasus-types.h"
#include <stdio.h>

class PigasusTypesTest : public TestFixture<PigasusTypesTest> {
 public:
  TEST_FIXTURE(PigasusTypesTest) {
    TEST_CASE(TestBasicListCreation); 
    TEST_CASE(TestListConcatenation);
    TEST_CASE(TestGetType); 
    TEST_CASE(TestListInBounds);
    TEST_CASE(TestListOutOfBounds);
    TEST_CASE(TestMapCreation);
    TEST_CASE(TestMapGetType);
    TEST_CASE(TestMapInBounds);
    TEST_CASE(TestMapOutOfBounds);
    TEST_CASE(TestFiles);  
  }

  void TestBasicListCreation() {
    List temp;
    string str_to_add = "hello";
    int int_to_add = 1;
    double float_to_add = 1.0234;

    temp.Append(str_to_add);
    temp.Append(int_to_add);
    temp.Append(float_to_add);

    ASSERT_EQUALS(str_to_add, *((string*)(temp[0])));
    ASSERT_EQUALS(int_to_add, *((int*)(temp[1])));
    ASSERT_EQUALS(float_to_add, *((double*)(temp[2])));
  }
  
  void TestListConcatenation() {
    List temp;
    string str_to_add = "hello";
    int int_to_add = 1;
    double float_to_add = 1.0234;
    
    List temp2;
    string str_to_add2 = "goodbye";
    int int_to_add2 = 2;
    double float_to_add2 = 2.0468;

    temp.Append(str_to_add);
    temp.Append(int_to_add);
    temp.Append(float_to_add);
    
    temp2.Append(str_to_add2);
    temp2.Append(int_to_add2);
    temp2.Append(float_to_add2);
    
    temp = temp + temp2;
    
    ASSERT_EQUALS(str_to_add, *((string*)(temp[0])));
    ASSERT_EQUALS(int_to_add, *((int*)(temp[1])));
    ASSERT_EQUALS(float_to_add, *((double*)(temp[2])));
    ASSERT_EQUALS(str_to_add2, *((string*)(temp[3])));
    ASSERT_EQUALS(int_to_add2, *((int*)(temp[4])));
    ASSERT_EQUALS(float_to_add2, *((double*)(temp[5])));
  }
  
  void TestGetType() {
    List temp;
    Map maptemp;
    int int_to_add;
    double float_to_add;
    File file;
    List temp2;
    
    temp.Append(temp);
    temp.Append(maptemp);
    temp.Append(int_to_add);
    temp.Append(float_to_add);
    temp.Append(file);
    temp.Append(temp2);
    
    ASSERT_EQUALS("list", temp.GetType(0));
    ASSERT_EQUALS("map", temp.GetType(1));
    ASSERT_EQUALS("int", temp.GetType(2));
    ASSERT_EQUALS("float", temp.GetType(3));
    ASSERT_EQUALS("file", temp.GetType(4));
    ASSERT_EQUALS("list", temp.GetType(5));
  }
  
  void TestListInBounds() {
    List temp;
    string str_to_add = "hello";
    int int_to_add = 1;
    double float_to_add = 1.0234;
    
    for (int i=0; i<temp.GetSize(); i++) {
      if ( i==0 ) {
        ASSERT_EQUALS(str_to_add, *((string*)(temp[0])));
      } else if ( i==1 ) {
        ASSERT_EQUALS(int_to_add, *((int*)(temp[1])));
      } else {
        ASSERT_EQUALS(float_to_add, *((double*)(temp[2])));
      }
    }
  }
  
  void TestListOutOfBounds() {
    List temp;
    string str_to_add = "hello";
    int int_to_add = 1;
    double float_to_add = 1.0234;
    void *element;
    
    for (int i=0; i< (temp.GetSize() + 1); i++) {
      element = temp[i];
    }
    
    ASSERT_EQUALS(NULL,element);
  }
  
  void TestMapCreation() {
    int a = 1;
    Map temp("test", a);
    
    ASSERT_EQUALS(a, *((int*)(temp["test"])));
      
    Map temp2;
    string str_to_add = "hello";
    int int_to_add = 1;
    double float_to_add = 1.0234;
    temp2 = Map("mystring",str_to_add) + Map("myint",int_to_add) + 
            Map("myfloat",float_to_add);
            
    ASSERT_EQUALS(str_to_add, *((string*)(temp2["mystring"])));
    ASSERT_EQUALS(int_to_add, *((int*)(temp2["myint"])));
    ASSERT_EQUALS(float_to_add, *((double*)(temp2["myfloat"]))); 
  }
  
  void TestMapGetType() {
    Map temp;
    List ltemp;
    int int_to_add;
    double float_to_add;
    File file;
    
    temp = Map("1" , temp) + Map("2", ltemp) + Map("3", int_to_add) 
          + Map("4",float_to_add) + Map("5",file);

    ASSERT_EQUALS("map", temp.GetType("1"));
    ASSERT_EQUALS("list", temp.GetType("2"));
    ASSERT_EQUALS("int", temp.GetType("3"));
    ASSERT_EQUALS("float", temp.GetType("4"));
    ASSERT_EQUALS("file", temp.GetType("5"));
  }
  
  void TestMapInBounds() {
    Map temp;
    string str_to_add = "hello";
    int int_to_add = 1;
    double float_to_add = 1.0234;
    temp = Map("mystring",str_to_add) + Map("myint",int_to_add) + 
           Map("myfloat",float_to_add);

    List keys = temp.GetKeys();
    string key;
    
    for (int i=0; i<keys.GetSize(); i++) {
      key = *((string*)(keys[i]));
      
      if ( i==0 ) {
        ASSERT_EQUALS(float_to_add, *((double*)(temp[key])));
      } else if ( i==1 ) {
        ASSERT_EQUALS(int_to_add, *((int*)(temp[key])));
      } else {
        ASSERT_EQUALS(str_to_add, *((string*)(temp[key])));
      }
    }
  }
  
  void TestMapOutOfBounds() {
    Map temp;
    void *val1;
    void *val2;
    string str;
    
    temp = Map("mystring","pigasus");
    
    val1 = temp["hello"];
    val2 = temp["notmystring"];
    str = *((string*)(temp["mystring"]));
    
    ASSERT_EQUALS(NULL,val1);
    ASSERT_EQUALS(NULL, val2);
    ASSERT_EQUALS("pigasus",str);
  }
   
  void TestFiles() {
    File temp("file1.txt");
    string temp2;
    temp2 = temp.Filename();
    
    ASSERT_EQUALS("file1.txt",temp2);
  }
    
};

REGISTER_FIXTURE(PigasusTypesTest);
\end{lstlisting}

\lstset{language=C++}
\begin{lstlisting}[caption=serialization-test.cc]
// Copyright 2009 Pigasus.
// GNU GPL v2.
// Author: Jordan Rupprecht.

#include "MiniCppUnit-2.5/MiniCppUnit.hxx"

#include <string>

#include "../src/pigasus-types.h"
#include "../src/serialization.h"

class SerializationTest : public TestFixture<SerializationTest> {
 private:

 public:
  TEST_FIXTURE(SerializationTest) {
    TEST_CASE(TestString);
    TEST_CASE(TestInt);
    TEST_CASE(TestFloat);
    TEST_CASE(TestList);
    TEST_CASE(TestMap);
    TEST_CASE(TestFile);
  }
  
  void TestString() {
    string x = "a b c d e";
    string serialized = Serialize(x);
    string unserialized = UnserializeString(serialized);
    ASSERT_EQUALS(x, unserialized);
  }
  
  void TestInt() {
    int x = -42;
    string serialized = Serialize(x);
    int unserialized = UnserializeInt(serialized);
    ASSERT_EQUALS(x, unserialized);
  }
  
  void TestFloat() {
    double x = 512.0f;
    string serialized = Serialize(x);
    double unserialized = UnserializeFloat(serialized);
    ASSERT_EQUALS(x, unserialized);
  }
  
  void TestList() {
    List x;
    Map m;
    
    m.Set("a", "b");
    
    x.Append(5);
    x.Append("hello world\n");
    x.Append(12.61);
    x.Append(m);
    string serialized = Serialize(x);
    List *unserialized = UnserializeList(serialized);
    ASSERT_EQUALS(*((int*)unserialized->Get(0)), 5);
    ASSERT_EQUALS(*((string*)unserialized->Get(1)), "hello world\n");
    ASSERT_EQUALS(*((double*)unserialized->Get(2)), 12.61);
    ASSERT_EQUALS(*((string*)((Map*)unserialized->Get(3))->Get("a")), "b");
    delete unserialized;
  }
  
  void TestMap() {
    Map x;
    List a;
    
    a.Append(42);
    a.Append("abc123");
    
    x.Set("x", "y");
    x.Set("z", 12);
    x.Set("w", a);
    
    string serialized = Serialize(x);
    Map *unserialized = UnserializeMap(serialized);
    ASSERT_EQUALS(*((string*)unserialized->Get("x")), "y");
    ASSERT_EQUALS(*((int*)unserialized->Get("z")), 12);
    ASSERT_EQUALS(*((int*)((List*)unserialized->Get("w"))->Get(0)), 42);
    ASSERT_EQUALS(*((string*)((List*)unserialized->Get("w"))->Get(1)), "abc123");
    delete unserialized;
  }
  
  void TestFile() {
    File x("abc.txt");
    string serialized = Serialize(x);
    File *unserialized = UnserializeFile(serialized);
    ASSERT_EQUALS(unserialized->Filename(), "abc.txt");
    delete unserialized;
  }
};

REGISTER_FIXTURE(SerializationTest);
\end{lstlisting}

